数组值只包含了字符和数字,更多类型增加不会影响以下method_*的排序(时间排序)
测试环境:版本 57.0.2987.133 (64-bit)
var arr1 = [1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 1, 2, 3, 4, 5, 6, "1", "2", "1", "2"];
var arr2 = [1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 1, 2, 3, 4, 5, 6];
while(arr1.length < 600000){
arr1 = arr1.concat(arr1);
arr2 = arr2.concat(arr2);
}
//
//
//
// method_1:新建数组-双循环-对比-push
Array.prototype.unique = function(){
var res = [this[0]],
len = this.length;
for(var i = 1; i < len; i ++){
var repeat = false,
rlen = res.length;
for (var j = 0; j < rlen; j ++){
if(this[i] === res[j]){
repeat = true;
break;
}
}
!repeat && res.push(this[i]);
}
return res;
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 18
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 10
//
//
//
// method_2:新建数组-排序-单循环-对比-push
Array.prototype.unique = function () {
this.sort(function (a, b) {
if (typeof a != typeof b && a == b) {
if (typeof a == "number") {
return -1;
} else {
return 1
}
}
return parseInt(a) - parseInt(b);
})
var res = [this[0]],
len = this.length;
for (var i = 1; i < len; i ++) {
var slen = res.length;
if (this[i] !== res[slen -1]) {
res.push(this[i]);
}
}
return res;
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 121
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 93
//
//
//
// method_3:新建数组-新建对象-单循环-对象对比-数组push
Array.prototype.unique = function () {
var res = [],
obj = {},
len = this.length;
for (var i = 0; i < len; i++) {
// 由于对象属性为字符串 1 和 "1" 相同,因此做不到 ===
!obj[this[i]] && res.push(this[i]) && (obj[this[i]] = 1);
}
return res;
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 8
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 5
//
//
// method_4:新建数组-循环-向后查询-数组push
Array.prototype.unique = function () {
var res = [],
len = this.length,
i, j;
for (i = 0; i < len; i++) {
for (j = i + 1; j < len; j++) {
if (this[i] === this[j]) {
j = false;
break;
}
}
j && res.push(this[i]);
}
return res;
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 28
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 17
//
//
//
// method_4:使用Set
Array.prototype.unique = function (){
var arr = new Set(this);
return [...arr];
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 75
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 60
//
//
//
// method_5:使用find/findIndex/indexOf
Array.prototype.unique = function(){
var res = [this[0]],
len = this.length;
for(var i = 1; i < len; i ++){
var repeat = false,
rlen = res.length;
if(!res.find((v,k)=>{return v === this[i]})){
res.push(this[i]);
}
// if(res.indexOf(this[i]) == -1){
// res.push(this[i]);
// }
// if(res.findIndex((v,k)=>{return v === this[i]}) == -1){
// res.push(this[i]);
// }
}
return res;
}
var timestamp = new Date().getTime();
arr1 = arr1.unique();
console.log(new Date().getTime() - timestamp); // 平均 110+
var timestamp = new Date().getTime();
arr2 = arr2.unique();
console.log(new Date().getTime() - timestamp); // 平均 65+
总结
method_1时间为 18 /10
,循环对比。
method_2时间为 121/93
, 如果依赖sort
排序(在字符和数字组合中更是依赖sort callback
)大大增加的时间,并且影响了原有数组顺序。
method_3时间为 8/5
, 无法区分字符和数字。
method_4时间为 28/7
,同method_1为循环对比,但是增加了内层循环次数。
method_5时间为 75/60
, 使用Set数据结构特性。
method_5时间为 110+/65+
, 使用find/findIndex/indexOf判断。
总体来说最佳选择为 method_1
但是推荐使用method_5----大道至简
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。